Skip to content

Fix crash when scorer LLM response is blocked by content filter#2072

Merged
rlundeen2 merged 13 commits into
microsoft:mainfrom
hannahwestra25:hannahwestra25/fix-scorer-content-filter-crash
Jul 11, 2026
Merged

Fix crash when scorer LLM response is blocked by content filter#2072
rlundeen2 merged 13 commits into
microsoft:mainfrom
hannahwestra25:hannahwestra25/fix-scorer-content-filter-crash

Conversation

@hannahwestra25

Copy link
Copy Markdown
Contributor

When the scorer's own LLM call is blocked by Azure content filtering (e.g., because it's grading harmful content), the response contains only an error piece with no text piece. The next() generator in _score_value_with_llm_async raises StopIteration, which becomes a RuntimeError inside the async coroutine.

This adds an explicit check before the next() call and raises a descriptive BadRequestException suggesting the user configure a scorer endpoint without content filtering.

hannahwestra25 and others added 3 commits June 23, 2026 21:07
When the scorer's own LLM call is blocked by Azure content filtering,
the response contains only an error piece with no text piece. The
next() call in _score_value_with_llm_async raises StopIteration, which
becomes a RuntimeError inside the async coroutine.

Add an explicit check for all-blocked response pieces before the next()
call and raise a descriptive BadRequestException instead.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread pyrit/score/scorer.py Outdated
Copilot AI and others added 2 commits July 1, 2026 04:56
A content-filter block always yields a single fully-blocked error piece, so the previous comment's claim about a salvageable text piece was inaccurate.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…scoring

The scoring transport was refactored into _run_llm_scoring_async
(pyrit/score/llm_scoring.py) with parsing delegated to ResponseHandler.
Move the all-pieces-blocked BadRequestException guard from the old inline
_score_value_with_llm_async body into the new transport helper, right before
the text-piece extraction that previously crashed on fully-blocked responses.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@rlundeen2

Copy link
Copy Markdown
Contributor

I'm going to work on this and take it over since Hannah is out

@rlundeen2 rlundeen2 self-assigned this Jul 10, 2026
rlundeen2 and others added 5 commits July 10, 2026 14:02
When the scorer's own LLM response is content-filtered, the transport now raises
a dedicated ScorerLLMResponseBlockedException instead of a generic
BadRequestException. The raise-vs-fallback policy lives in the Scorer (per
framework.md): score_async catches the exception and, when
raise_if_scorer_blocks is False, returns the scorer's type default (False / 0.0)
via _build_fallback_score instead of raising. Defaults to raising.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…m policy

Use 'scorer's LLM response' consistently in llm_scoring.py and drop the
Scorer.raise_if_scorer_blocks reference from the transport docstring/comment so
the transport doesn't name the Scorer's policy attribute.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The crash this PR fixes is a StopIteration when no text piece exists in the
scorer's response. The previous guard keyed on 'all pieces blocked', which left
two gaps: an empty piece list spuriously raised (all() over empty is True), and
a non-blocked response with no text piece fell through and crashed again.

Resolve the text piece safely and branch on why it's missing: a content-filter
block raises ScorerLLMResponseBlockedException (routed through the Scorer's
raise_if_scorer_blocks policy), while any other no-text response raises
EmptyResponseException so a genuinely empty/malformed response surfaces as a real
error instead of being silently converted to a default score.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@rlundeen2 rlundeen2 added this pull request to the merge queue Jul 11, 2026
Merged via the queue into microsoft:main with commit fcea078 Jul 11, 2026
53 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants